#include <iostream>
#include <vector>
#include "Thread.hpp"
#include <unistd.h>
#include"LockGuard.hpp"
using namespace ThreadModule;

// 定义全局锁
// pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;

int g_tickets = 10000;
const int num = 4;
class ThreadData
{
public:
    ThreadData(int &tickets, const std::string &name,pthread_mutex_t &mutex) : _tickets(tickets),
                                                        _name(name) ,
                                                        _total(0),  // 初始化为0
                                                        _mutex(mutex)
                                                        {}
    ~ThreadData() {}

public:
    int &_tickets;
    std::string _name;
    int _total;
    pthread_mutex_t& _mutex;
};

// void GetTicktes(ThreadData *td)
// {
//     while (1)
//     {

//         // pthread_mutex_lock(&gmutex); // 加锁

//         pthread_mutex_lock(&td->_mutex); // 加锁
//         if (td->_tickets > 0)
//         {
//             usleep(1000);

//             // printf(" tickets: %d\n", td->_tickets);
//             td->_tickets--; 
//             // pthread_mutex_unlock(&gmutex); // 解锁

//             pthread_mutex_unlock(&td->_mutex); // 解锁
//             td->_total++;
//         }
//         else
//         {
//             // pthread_mutex_unlock(&gmutex); // 解锁

//             pthread_mutex_unlock(&td->_mutex); // 解锁
//             break;
//         }
//     }
// }


void GetTicktes(ThreadData *td)
{
    while (1)
    {
        LockGuard guard(&td->_mutex); // 临时对象，此时就加锁成功
        if (td->_tickets > 0)
        {
            usleep(1000);
            td->_tickets--; 
            td->_total++;
        }
        else
        {
            break;
        }
    }
}


int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex,nullptr);// 局部锁初始化

    std::vector<Thread<ThreadData *>> threads;
    std::vector<ThreadData *> datas;
    for (int i = 0; i < num; i++)
    {
        // char *threadname = new char[64];
        // snprintf(threadname, 64, "thread-%d", i + 1);
        std::string name = "thread-"+std::to_string(i+1);
        ThreadData *td = new ThreadData(g_tickets, name,mutex);
        threads.emplace_back(GetTicktes, td, name);
        datas.emplace_back(td);
    }

    // 这里需要用引用，否则就是一个新的对象去调用start和join
    
    // for (auto e : threads)
    for (auto& e : threads)
    {
        e.Start();
    }

    // for (auto e : threads)
    for (auto& e : threads)
    {
        e.Join();
    }
    for(auto& e: datas)
    {
        std::cout<<e->_name << ": " <<e->_total<<std::endl;
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}